/**
 * @author Michael,Sep 11, 2012
 *
 */
package com.tm.util;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import com.util.SysCache;

/**
 * @author Michael
 */
public class DateUtil {
	public static final int	day_start_hour			= Integer.parseInt(SysCache.getInstance().getSysConfig("day.start.hour"));
	public static final int	default_working_hour	= Integer.parseInt(SysCache.getInstance().getSysConfig("default.working.hours"));
	public static final int	day_end_hour			= day_start_hour + default_working_hour;
	/**
	 * 默认加班时间，如果结束时间在第二天的开始 default_overtime_min 小时以内，则允许加班将任务完成时间调整到前一天<br>
	 * 例如：default_overtime_min = 60.<br>
	 * 如果任务结束时间刚好在第二天前60分钟内，则将该任务结束时间调整为今天加班
	 */
	public static final int	default_overtime_min	= Integer.parseInt(SysCache.getInstance().getSysConfig("default.overtime.min"));

	public static float getWorkHours(Date date) {
		float hours = 0.0f;
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int weekDay = c.get(Calendar.DAY_OF_WEEK);
		if (weekDay != 1 && weekDay != 7) {
			hours = default_working_hour;
		}
		return hours;
	}

	private static Calendar getNextWorkingDay(Calendar date, Boolean resetTime) {
		Calendar result = Calendar.getInstance();
		result.setTime(date.getTime());
		if (resetTime == null) {
			resetTime = false;
		}
		do {
			result.add(Calendar.DATE, 1);
		} while (getWorkHours(result.getTime()) < default_working_hour);

		if (resetTime != null && resetTime.booleanValue() == true) {
			resetWorkTime(result, true);
		}
		System.out.println("下个工作日是：" + formatDate(result.getTime(), resetTime));
		return result;
	}
	
	/**
	 * 获得前一个工作日
	 * @author Michael,Sep 19, 2012
	 * @param date
	 * @param resetTime 是否重置时间
	 * @param fetchStart 重置时间时是去开始时间还是结束时间， 仅当 resetTime 为true时生效
	 * @return
	 */
	private static Calendar getPreWorkingDay(Calendar date, Boolean resetTime, boolean fetchStart) {
		Calendar result = Calendar.getInstance();
		result.setTime(date.getTime());
		if (resetTime == null) {
			resetTime = false;
		}
		do {
			result.add(Calendar.DATE, -1);
		} while (getWorkHours(result.getTime()) < default_working_hour);

		if (resetTime != null && resetTime.booleanValue() == true) {
			if(fetchStart){
				resetWorkTime(result, true);
			}else{
				resetWorkTime(result, false);
			}
		}
		System.out.println("前一个工作日是：" + formatDate(result.getTime(), resetTime));
		return result;
	}

	private static void resetWorkTime(Calendar c, boolean resetToStart) {
		if(resetToStart){
			c.set(Calendar.HOUR_OF_DAY, day_start_hour);
		}else{
			c.set(Calendar.HOUR_OF_DAY, day_end_hour);
		}
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		c.set(Calendar.MILLISECOND, 0);
	}

	public static Timestamp addWorkingHours(Date date, float hours) {
		int totalHour = (int) Math.floor(hours);
		int totalMin = Math.round((hours % 1) * 60);
		int totalDay = totalHour / default_working_hour;
		totalHour = totalHour % default_working_hour;

		System.out.println("增加时间：" + totalDay + "天 " + totalHour + "小时 " + totalMin + "分钟");

		Calendar c = Calendar.getInstance();
		c.setTime(date);

		// 增加默认的延迟时间
//		c.add(Calendar.MINUTE, default_delay_min);

		if (c.get(Calendar.HOUR_OF_DAY) >= day_end_hour) {
			// 如果当前时间已经是下班时间则从下一个工作日开始增加时间
			c = getNextWorkingDay(c, true);
		} else if (c.get(Calendar.HOUR_OF_DAY) < day_start_hour) {
			resetWorkTime(c, true);
		}

		// 开始计算天数
		if (totalDay > 0) {
			for (int i = 1; i <= totalDay; i++) {
				c = getNextWorkingDay(c, false);
			}
		}

		// 计算小时数
		// 比较当前时间与当天结束时间之差
		if (totalHour > 0) {
			int leftHoursOfDay = day_end_hour - c.get(Calendar.HOUR_OF_DAY);
			if (leftHoursOfDay > 0) {
				// 当天尚未结束
				if (leftHoursOfDay >= totalHour) {
					c.add(Calendar.HOUR_OF_DAY, totalHour);
				} else {
					c = getNextWorkingDay(c, true);
					totalHour = totalHour - leftHoursOfDay;
					c.add(Calendar.HOUR_OF_DAY, totalHour);
				}
			} else if (leftHoursOfDay == 0) {
				// 当天已经结束
				c = getNextWorkingDay(c, true);
				c.add(Calendar.HOUR_OF_DAY, totalHour);
			} else if (leftHoursOfDay < 0) {
				c = getNextWorkingDay(c, true);
			}
		}
		
		// 计算分钟数
		if (totalMin > 0) {
			if(c.get(Calendar.HOUR_OF_DAY) >= day_end_hour){
				c = getNextWorkingDay(c, true);
			}
			c.add(Calendar.MINUTE, totalMin);
		}
		
		//如果允许加班则添加时间修正
		if(default_overtime_min > 0){
			int difMin = c.get(Calendar.MINUTE);
			difMin += (c.get(Calendar.HOUR_OF_DAY) - day_start_hour) * 60;
			if(difMin > 0 && difMin <= default_overtime_min){
				//在时间调整的范围内
				c = getPreWorkingDay(c, true, false);
				c.add(Calendar.MINUTE, difMin);
			}
		}

		return new Timestamp(c.getTime().getTime());
	}
	
	
	public static Calendar  getWorkingTime(Calendar c){
		if (c.get(Calendar.HOUR_OF_DAY) >= day_end_hour) {
			// 如果当前时间已经是下班时间则从下一个工作日开始增加时间
			c = getNextWorkingDay(c, true);
		} else if (c.get(Calendar.HOUR_OF_DAY) < day_start_hour) {
			resetWorkTime(c, true);
		}
		return c;
	}
	

	public static String formatDate(Date date, boolean withHour) {
		Calendar c = Calendar.getInstance(Locale.SIMPLIFIED_CHINESE);
		c.setTime(date);
		Locale locale = Locale.SIMPLIFIED_CHINESE;
		DateFormat f = null;
		if (withHour) {
			f = new SimpleDateFormat("MMMd HH:mm", locale);
		} else {
			f = new SimpleDateFormat("yyyy-MMMd,EEE ", locale);
		}
		return f.format(c.getTime());
	}

	public static void main(String[] args) {
		Calendar c = Calendar.getInstance();
		c.set(Calendar.HOUR_OF_DAY, 18);
		c.set(Calendar.MINUTE, 50);
		System.out.println("开始时间: " + DateUtil.formatDate(c.getTime(), true));
		Date d = addWorkingHours(c.getTime(), 24.6f);
		System.out.println("结束时间: " + DateUtil.formatDate(d, true));
	}

}
